package org.bwapi.bridge.model;

import java.util.Set;
import java.util.Map.Entry;

import org.apache.commons.collections15.Transformer;
import org.bwapi.bridge.swig.ChokepointGetRegionsPair;
import org.bwapi.bridge.swig.ChokepointGetSidesPair;
import org.bwapi.bridge.swig.ChokepointSet;
import org.bwapi.bridge.swig.ChokepointSetIterator;
import org.bwapi.bridge.swig.ChokepointSpacelessSet;
import org.bwapi.bridge.swig.ChokepointSpacelessSetIterator;
import org.bwapi.bridge.swig.SWIGTYPE_p_Chokepoint;
import org.bwapi.bridge.swig.SWIGTYPE_p_std__setT_BWTA__Chokepoint_p_t;
import org.bwapi.bridge.swig.SWIGTYPE_p_std__setT_Chokepoint_p_t;
import org.cretz.swig.collection.NativeSet;
import org.cretz.swig.util.SwigUtils;

/**
 * Chokepoint
 * 
 * @see <a href="http://code.google.com/p/bwta/wiki/Chokepoint">Chokepoint</a>
 * 
 * @author Chad Retz
 * 
 * @since 0.2
 */
public class Chokepoint {
	private static final Transformer<Chokepoint, org.bwapi.bridge.swig.Chokepoint> FROM = 
		new Transformer<Chokepoint, org.bwapi.bridge.swig.Chokepoint>() {
			@Override
			public org.bwapi.bridge.swig.Chokepoint transform(Chokepoint chokepoint) {
				return chokepoint.getChokepoint();
			}
		};
		
	private static final Transformer<org.bwapi.bridge.swig.Chokepoint, Chokepoint> TO = 
		new Transformer<org.bwapi.bridge.swig.Chokepoint, Chokepoint>() {
			@Override
			public Chokepoint transform(org.bwapi.bridge.swig.Chokepoint chokepoint) {
				return new Chokepoint(chokepoint);
			}
		};

	private static final Transformer<Chokepoint, SWIGTYPE_p_Chokepoint> FROM_SPACELESS = 
		new Transformer<Chokepoint, SWIGTYPE_p_Chokepoint>() {
			@Override
			public SWIGTYPE_p_Chokepoint transform(Chokepoint chokepoint) {
				return chokepoint.getPointer();
			}
		};
		
	private static final Transformer<SWIGTYPE_p_Chokepoint, Chokepoint> TO_SPACELESS = 
		new Transformer<SWIGTYPE_p_Chokepoint, Chokepoint>() {
			@Override
			public Chokepoint transform(SWIGTYPE_p_Chokepoint chokepoint) {
				return new Chokepoint(chokepoint);
			}
		};
		
	static Set<Chokepoint> newSet(SWIGTYPE_p_std__setT_BWTA__Chokepoint_p_t nativeSet) {
		return new NativeSet<Chokepoint, org.bwapi.bridge.swig.Chokepoint>(
				org.bwapi.bridge.swig.Chokepoint.class, ChokepointSetIterator.class, 
				nativeSet, ChokepointSet.class, FROM, TO);
	}
		
	static Set<Chokepoint> newSet(SWIGTYPE_p_std__setT_Chokepoint_p_t nativeSet) {
		return new NativeSet<Chokepoint, SWIGTYPE_p_Chokepoint>(
				SWIGTYPE_p_Chokepoint.class, ChokepointSpacelessSetIterator.class, 
				nativeSet, ChokepointSpacelessSet.class, FROM_SPACELESS, TO_SPACELESS);
	}

	private final org.bwapi.bridge.swig.Chokepoint chokepoint;

	Chokepoint(org.bwapi.bridge.swig.Chokepoint chokepoint) {
		this.chokepoint = chokepoint;
	}
	
	Chokepoint(SWIGTYPE_p_Chokepoint chokepoint) {
		this(SwigUtils.getSwigPointer(SwigUtils.getSwigPointer(chokepoint), 
				false, org.bwapi.bridge.swig.Chokepoint.class));
	}

	org.bwapi.bridge.swig.Chokepoint getChokepoint() {
		return chokepoint;
	}
	
	SWIGTYPE_p_Chokepoint getPointer() {
		return SwigUtils.getSwigPointer(chokepoint, SWIGTYPE_p_Chokepoint.class);
	}

	public Entry<Region, Region> getRegions() {
		final ChokepointGetRegionsPair pair = chokepoint.getRegions();
		return new Entry<Region, Region>() {
			@Override
			public Region getKey() {
				org.bwapi.bridge.swig.Region region = pair.getFirst();
				return region == null ? null : new Region(region);
			}

			@Override
			public Region getValue() {
				org.bwapi.bridge.swig.Region region = pair.getSecond();
				return region == null ? null : new Region(region);
			}

			@Override
			public Region setValue(Region value) {
				throw new UnsupportedOperationException();
			}
		};
	}

	public Entry<Position, Position> getSides() {
		final ChokepointGetSidesPair pair = chokepoint.getSides();
		return new Entry<Position, Position>() {
			@Override
			public Position getKey() {
				org.bwapi.bridge.swig.Position position = pair.getFirst();
				return position == null ? null : new Position(position);
			}

			@Override
			public Position getValue() {
				org.bwapi.bridge.swig.Position position = pair.getSecond();
				return position == null ? null : new Position(position);
			}

			@Override
			public Position setValue(Position value) {
				throw new UnsupportedOperationException();
			}
		};		
	}

	public Position getCenter() {
		return new Position(chokepoint.getCenter());
	}

	public double getWidth() {
		return chokepoint.getWidth();
	}

}
